import { Tree } from 'antd';
import React, { useEffect, useState } from 'react';

type MenuItemProps = {
  title: string;
  key: string;
  parentId: string;
  children: MenuItemProps[];
  childrenIds?: string[];
};

//查找子节点id，包含所有子孙节点
const findchildIds = (targetArr: MenuItemProps[]) => {
  let resultIds: string[] = [];

  function find(arr: MenuItemProps[]) {
    arr.forEach((item) => {
      resultIds.push(item.key);
      if (item?.children?.length) {
        find(item?.children);
      }
    });
  }

  find(targetArr);

  return resultIds;
};

// 菜单扁平化
const menuFlatten = (menus: MenuItemProps[]) => {
  const result: MenuItemProps[] = [];

  function addMenuArr(targetArr: MenuItemProps[]) {
    targetArr.forEach((item) => {
      result.push(item);
      if (item.children) {
        //查找子节点id，包含所有子孙节点
        item.childrenIds = findchildIds(item.children || []);
        //item.childrenIds = item.children.map((item) => item.key);
        addMenuArr(item.children);
      }
    });
  }

  addMenuArr(menus);
  return result;
};

const handleSelectMenuIds = (_ids: string[] | undefined, menusList: MenuItemProps[]) => {
  const resultIds: string[] = [];
  if (!Array.isArray(_ids) || !_ids.length || !Array.isArray(menusList) || !menusList.length) {
    return _ids;
  }

  const ids = _ids.map((id) => id.toString());

  //检查一个数组是否是另一个数组的子集
  const isSubset = (array1: string[], array2: string[]) =>
    array2.every((element) => array1.includes(element));

  ids.forEach((id) => {
    let allSelected = false;
    menusList.forEach((item) => {
      if (item.key === id) {
        const childrenIds = item.childrenIds || [];
        // id子集没有全部选中，则取消父节点的选中状态；
        if (isSubset(ids, childrenIds)) {
          allSelected = true;
        }
        // 子集为空，默认选中子集
        if (childrenIds?.length && childrenIds.every((i) => !ids.includes(i))) {
          allSelected = true;
          resultIds.push(...childrenIds);
        }
      }
    });
    if (allSelected) {
      resultIds.push(id);
    }
  });
  return [...new Set(resultIds)];
};

const Index: React.FC<{
  value?: string[];
  treeData?: MenuItemProps[];
  onChange?: (keys: string[]) => void;
}> = ({ value, onChange, treeData }) => {
  const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
  const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);
  const [checkedKeys, setCheckedKeys] = useState<React.Key[]>([]);
  const [initStatus, setInitStatus] = useState<boolean>(false);

  const onExpand = (expandedKeysValue: React.Key[]) => {
    setExpandedKeys(expandedKeysValue);
    setAutoExpandParent(false);
  };

  const onCheck = (checkedKeysValue: React.Key[]) => {
    const stringKeys = (checkedKeysValue as string[]).filter(Boolean);
    setCheckedKeys(stringKeys);
    onChange?.(stringKeys);
  };

  // 修改这个 useEffect，添加安全检查
  useEffect(() => {
    // 只在初始化时执行一次
    if (!initStatus && treeData && Array.isArray(value)) {
      const ids = handleSelectMenuIds(
        value.filter(Boolean).map((id) => String(id)), // 添加过滤和类型转换
        menuFlatten(treeData),
      );
      setCheckedKeys(ids);
      // 只在值真正改变时才触发 onChange
      if (JSON.stringify(ids) !== JSON.stringify(value)) {
        onChange?.(ids);
      }
      setInitStatus(true);
    }
  }, [value, treeData, initStatus]);

  // 修改 value 更新的 useEffect
  useEffect(() => {
    if (initStatus && Array.isArray(value)) {
      setCheckedKeys(value.filter(Boolean).map(String));
    }
  }, [value, initStatus]);

  return (
    <div
      style={{
        border: '1px solid #d9d9d9',
        marginBlockStart: 5,
        padding: '10px 4px',
        borderRadius: 2,
        maxHeight: '550px',
        overflow: 'auto',
      }}
    >
      <Tree
        checkable
        onExpand={onExpand}
        expandedKeys={expandedKeys}
        autoExpandParent={autoExpandParent}
        onCheck={onCheck}
        checkedKeys={checkedKeys}
        treeData={treeData}
      />
    </div>
  );
};
export default Index;
